/***********************************************************************************
 * @ file    : demo.h
 * @ author  : yang yang
 * @ version : 0.9
 * @ date    : 2021.09.20
 * @ brief   : 演示camera svc的使用
 *
 * @Copyright (c) 2016  chuangmi inc.
 ************************************************************************************/

#ifndef __CAMERA_DEMO_H__
#define __CAMERA_DEMO_H__

#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdint.h>

#include "imi_camera_svc.h"

#define MEDIA_PORT                      8088
#define CONTROL_PORT                    8089
#define TOKEN                           "11111111"

#define VIDEO_FRAME                     0
#define AUDIO_FRAME                     1

#define MAX_CMD_LEN                     32
#define CMD_HEADER                      0x5AA5

#define MAX_CLIENTS                     (3)
#define FRAME_INFO_SIZE                 (256)
#define MIN_VIDEO_SIZE                  (4 * 1024)
#define MAX_VIDEO_SIZE                  (48 * 1024)
#define AUDIO_SIZE                      (2048)
#define INFO_SEED                       "1234567890"
#define DATA_SEED                       "abcdefghijklmnopqrstuvwxyz"

#define CMD_MSG                         "{\"id\":\"%d\",\"cmd\":\"%d\",\"msg\":\"%s\"}"
#define MSG_ACK                         "{\"id\":\"%d\",\"code\":\"%d\",\"message\":\"%s\"}"

#define CMD_MSG_REQ_BASE                "{\"header\":%d,\"cmd\":%d,\"id\":%d,\"data_len\":%d,\"crc\":%d,\"data\":{%s}}"
#define CMD_MSG_REQ_EXTENE              "\"timeout\":%d"
#define CMD_MSG_REQ_EXT_QUALITY         "\"quality\":%d"

#define CMD_MSG_ACK_BASE                "{\"id\":%d,\"cmd\":%d,\"code\":%d,\"message\":\"%s\",\"result\":{%s}}"
#define CMD_MSG_ACK_EXTEND              "\"productKey\":\"%s\",\"deviceName\":\"%s\",\"fwVersion\":\"%s\",\"mac\":\"%s\",\"protocolVersion\":\"%s\",\"token\":\"null\",\"extraDeviceInfo\":{},\"bindResultInfo\":{\"isLocal\":%d, \"isBind\":%s}"

typedef enum {
    VIDEO_NO_STREAM = 0x0,
    VIDEO_MAIN_STREAM,
    VIDEO_SUB_STREAM,
    VIDEO_THR_STREAM,
    VIDEO_STREAM_COUNT
} video_quality_e;

typedef enum {
    DIRECT_CODEC_UNKNOWN,
    DIRECT_CODEC_VIDEO_MPEG4,
    DIRECT_CODEC_VIDEO_MJPEG,
    DIRECT_CODEC_VIDEO_H263,
    DIRECT_CODEC_VIDEO_H264,
    DIRECT_CODEC_VIDEO_HEVC,
    DIRECT_CODEC_VIDEO_H265 = DIRECT_CODEC_VIDEO_HEVC,
    DIRECT_CODEC_VIDEO_CUSTOM,
    DIRECT_CODEC_AUDIO_PCM = 1024,
    DIRECT_CODEC_AUDIO_ADPCM,
    DIRECT_CODEC_AUDIO_G711U,
    DIRECT_CODEC_AUDIO_G711A,
    DIRECT_CODEC_AUDIO_G726,
    DIRECT_CODEC_AUDIO_MP3,
    DIRECT_CODEC_AUDIO_AAC,
    DIRECT_CODEC_AUDIO_SPEEX,
    DIRECT_CODEC_AUDIO_CUSTOM
} direct_codec_e;

typedef enum {
    WIFI_DIRECT_CMD_AUTHENTICATE_REQ = 0x100,
    WIFI_DIRECT_CMD_AUTHENTICATE_RESP,
    WIFI_DIRECT_CMD_BIND_START,                 /**< C->S, bind start */
    WIFI_DIRECT_CMD_BIND_START_RESP,            /**< S->C, bind start response */
    WIFI_DIRECT_CMD_BIND_STOP,                  /**< C->S, bind stop */
    WIFI_DIRECT_CMD_BIND_STOP_RESP,             /**< S->C, bind stop response */
    WIFI_DIRECT_CMD_TOKEN_REQ,                  /**< S->C, token req */
    WIFI_DIRECT_CMD_TOKEN_RESP,                 /**< C->S, token response */
    WIFI_DIRECT_CMD_TOKEN_PARSE_RESULT,         /**< S->C, token parse result */
    WIFI_DIRECT_CMD_VIDEO_START,                /**< C->S, video start */
    WIFI_DIRECT_CMD_VIDEO_STOP,                    /**< C->S, video stop */
    WIFI_DIRECT_CMD_AUDIO_START,                /**< C->S, audio start */
    WIFI_DIRECT_CMD_AUDIO_STOP,                    /**< C->S, audio stop */
    WIFI_DIRECT_CMD_SPEAKER_START_REQ,            /**< C->S, speaker start req */
    WIFI_DIRECT_CMD_SPEAKER_START_RESP,            /**< C->S, speaker start resp */
    WIFI_DIRECT_CMD_SPEAKER_STOP,                /**< C->S, speaker stop */
    WIFI_DIRECT_CMD_STREAM_CTRL_REQ,            /**< C->S, video quality req */
    WIFI_DIRECT_CMD_STREAM_CTRL_RESP,            /**< S->C, video quality response */
    WIFI_DIRECT_CMD_GET_AUDIO_FORMAT_REQ,        /**< C->S, get audio format */
    WIFI_DIRECT_CMD_GET_AUDIO_FORMAT_RESP,      /**< S->C, audio format response */
    WIFI_DIRECT_CMD_PLAYLIST_REQ,                /**< C->S, playlist request */
    WIFI_DIRECT_CMD_PLAYLIST_RESP,                /**< S->C, playlist response */
    WIFI_DIRECT_CMD_PLAYBACK_REQ,                /**< C->S, playback request */
    WIFI_DIRECT_CMD_PLAYBACK_RESP,                /**< S->C, playback response */
    WIFI_DIRECT_CMD_PLAYBACK_SET_SPEED,            /**< C->S, playback speed request*/
    WIFI_DIRECT_CMD_PLAYBACK_SET_SPEED_RESP,    /**< S->C, playback speed response*/
    WIFI_DIRECT_CMD_PLAYBACK_SEEK,                /**< C->S, playback seek request*/
    WIFI_DIRECT_CMD_PLAYBACK_SEEK_RESP,            /**< S->C, playback seek response*/
    WIFI_DIRECT_CMD_DEVINFO_REQ,                /**< C->S, device info request */
    WIFI_DIRECT_CMD_DEVINFO_RESP,                /**< S->C, device info response */
    WIFI_DIRECT_CMD_MOTOR_REQ,                    /**< C->S, device motor control */
    WIFI_DIRECT_CMD_MOTOR_RESP,                    /**< S->C, device motor control response */
    WIFI_DIRECT_CMD_TRANSLATOR,                 /**< C->S, cmd translator */
    WIFI_DIRECT_CMD_TRANSLATOR_RESP,            /**< S->C, cmd translator response*/
    WIFI_DIRECT_CMD_MAX = 0x1001
} wifi_direct_cmd_e;

typedef enum {
    PLAY_STATUS_NORMAL = 0x10,
    PLAY_STATUS_LIVE,
    PLAY_STATUS_TALK,
    PLAY_STATUS_PLAYBACK,
    PLAY_STATUS_MAX = 0x100
} play_status_e;

typedef struct session_info_s {
    imi_camera_svc_event_t status;
    play_status_e is_playing;
    video_quality_e  video_quality;
} *session_info_t;

typedef struct server_ctx_s {
    IMI_BOOL is_running;
    int  talk_session;
    imi_camera_svc_t svc;
    struct session_info_s sessions[MAX_CLIENTS];
} *server_ctx_t;

typedef struct {
    int         codec_type;                     /**< 编码类型 */
    uint32_t    seq;                            /**< 码流序列号，按帧获取帧序号，按包获取包序号 */
    uint64_t    timestamp;                      /**< 时间戳，单位us */
    uint32_t    length;                         /**< 码流包长度 */
    uint32_t    key_frame;                      /**< 码流类型 0=P, 1=I*/
    uint32_t    frame_type;                     /* 主流或辅流 */
    uint32_t    playback;                       /* 是否是回看帧，1 是回看帧，非1 不是回看帧 */
    int         width;
    int         height;
    unsigned char data[0];
} Direct_VideoFrame;

typedef struct {
    int         codec_type;                     /**< 编码类型 */
    uint32_t    seq;                            /**< 音频帧序号 */
    uint64_t    timestamp;                      /**< 音频帧数据时间戳 */
    uint32_t    length;                         /**< 音频帧长度 */
    uint32_t    samplerate;                     /**< 音频采样率 */
    uint32_t    bitwidth;                       /**< 音频采样精度 16 = AUDIO_BIT_WIDTH_16*/
    uint32_t    soundmode;                      /**< 音频声道模式 1 = AUDIO_SOUND_MODE_MONO, 2 = AUDIO_SOUND_MODE_STEREO */
    unsigned char data[0];
} Direct_AudioFrame;

#if (IMI_AUDIO_FORMAT == 0)
    #define DIRECT_AUDIO_CODEC                  DIRECT_CODEC_AUDIO_G711A
#elif (IMI_AUDIO_FORMAT == 1)
    #define DIRECT_AUDIO_CODEC                  DIRECT_CODEC_AUDIO_G711U
#elif (IMI_AUDIO_FORMAT == 2)
    #define DIRECT_AUDIO_CODEC                  DIRECT_CODEC_AUDIO_G726
#elif (IMI_AUDIO_FORMAT == 3)
    #define DIRECT_AUDIO_CODEC                  DIRECT_CODEC_AUDIO_AAC
#elif (IMI_AUDIO_FORMAT == 4)
    #define DIRECT_AUDIO_CODEC                  DIRECT_CODEC_AUDIO_CUSTOM
#endif

#if defined(DEVELOP_MODE)
    #define log_warning                         printf
    #define log_debug                           printf
    #define log_info                            printf
    #define log_err                             printf
    #define log_error                           printf
#endif

#ifdef __cplusplus
extern "C" {
#endif

int demo_camsvc(int argc, char* argv[]);

int demo_camcli(int argc, char* argv[]);

#ifdef __cplusplus
}
#endif

#endif // __CAMERA_DEMO_H__
